package com.study.rpc06.server;

import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 06中根据客户端发送的Class类型，进行加载执行指定的方法返回结果。
 * 寻找Class类型可以根据全限定名、spring注入、map缓存等等方式实现。
 */
public class Server {

    private static boolean running = true;

    public static void main(String[] args) throws Exception{
        ServerSocket ss = new ServerSocket(8888);
        while (running){
            Socket s = ss.accept();
            process(s);
            s.close();
        }
        ss.close();
    }

    private static void process(Socket s) throws Exception{
        InputStream in = s.getInputStream();
        OutputStream out = s.getOutputStream();
        ObjectInputStream ois = new ObjectInputStream(in);
        ObjectOutputStream oos = new ObjectOutputStream(out);

        String clazzName = ois.readUTF();
        String methodName = ois.readUTF();
        Class[] parameterTypes = (Class[]) ois.readObject();
        Object[] args = (Object[]) ois.readObject();

        Class clazz = null;

        //从服务注册表找到具体的类
        clazz = findClassByName(clazzName);;

        Method method = clazz.getMethod(methodName, parameterTypes);
        Object o = method.invoke(clazz.getDeclaredConstructor().newInstance(), args);

        oos.writeObject(o);
        oos.flush();
    }
    /**
     * 根据className寻找class，过程有各种各样，此处简单直接赋值
     */
    private static Class findClassByName(String clazzName) throws Exception{
        if (Class.forName(clazzName).isAssignableFrom(UserServiceImpl.class)) {
            return UserServiceImpl.class;
        }
        return Object.class;
    }
}
